<?php
require_once("Panel/User.php");
require_once("Session/Sign.php");

/**
 * session engine
 *
 */
class user_session {
	private $php_session_id;
	private $native_session_id;
	private $logged_in;
	private $user_id;
	private $user_stanowisko;
	private $session_timeout;      # minutowy maksymalny czas nieaktywno�ci sesji
	private $session_lifespan;    # godzinny maksymalny czas trwania sesji.
	private $subdomena;
	private $__logged_user;
	
	public function __construct() {
		global $config, $smarty, $user;
		
		$this->session_timeout = 60*20;
		$this->session_lifespan = 60*60;
		
		$smarty->assign('session_timeout',$this->session_timeout);
		# Inicjalizuje mechanizm obslugi sesji
		session_set_save_handler(
		array(&$this, '_session_open_method'),
		array(&$this, '_session_close_method'),
		array(&$this, '_session_read_method'),
		array(&$this, '_session_write_method'),
		array(&$this, '_session_destroy_method'),
		array(&$this, '_session_gc_method')
		);
		# Sprawdza przesłane cookie o ile je przesłano; jeśeli wygląda podejrzanie zostaja z miejsca anulowane
		if (isset($_COOKIE["PHPSESSID"])) {
			# Kontrola bezpieczeństwa i ważności
			$this->php_session_id = $_COOKIE["PHPSESSID"];
			$this->subdomena = $config->subdomena;
			$stmt = "SELECT id FROM ".SESSI." WHERE identyfikator_sesji_ascii = '" . $this->php_session_id . "' 
				AND ((strftime('%s','now') - strftime('%s',utworzono) ) < ' " . $this->session_lifespan . "') 
				AND user_agent = '{$this->subdomena}' 
				AND ((strftime('%s','now') - strftime('%s',ostatnie_dzialanie)) <= '".$this->session_timeout."' 
				OR ostatnie_dzialanie IS NULL)";
			$result = tools::__adodb("getOne",$stmt);
			
			if ( empty($result) ) {		

				# Ustawia znacznik niepowodzenia
				$failed = 1;
				# Usuwa z bazy danych - w tym samym czasie usuwane s� przeterminowane sesje
				$result = tools::__adodb("exec","DELETE FROM ".SESSI." 
					WHERE identyfikator_sesji_ascii = '". $this->php_session_id . "' 
					OR (strftime('%s','now') - strftime('%s',utworzono)) > '{$this->session_lifespan}'");
					
				# Usuwa nieprzydatne zmienne sesji
				$result = tools::__adodb("exec","DELETE FROM ".SESSV." WHERE identyfikator_sesji 
					NOT IN (SELECT id FROM ".SESSI.")");
				# Pozbywa si� identyfikatora, wymuszaj�c na PHP nadanie nowego
				unset($_COOKIE["PHPSESSID"]);
			}else{
				# Usuwa z bazy danych - w tym samym czasie usuwane s� przeterminowane sesje
				
				$result = tools::__adodb("exec","DELETE FROM ".SESSI." WHERE  (strftime('%s','now') - strftime('%s',ostatnie_dzialanie)) > '{$this->session_lifespan}'");
					
				# Usuwa nieprzydatne zmienne sesji
				$result = tools::__adodb("exec","DELETE FROM ".SESSV." WHERE identyfikator_sesji 	NOT IN (SELECT id FROM ".SESSI.")");
		
			}
		};
		# Ustawia czas �ycia cookie
		session_set_cookie_params($this->session_lifespan);
		# Wywo�uje metod� session_start by zainicjowa� sesj�
		session_start();

		# informacje o uzytkowniku
		$__user = $this->_get_status_user_info();
		

		

		$config->__user = $this->user_id = $__user['identyfikator_uzytkownika'];
		$config->__logg = $this->logged_in = $__user['zalogowany'];		


		// logowanie - wylogowywanie
		$this->__logged_user = SignController::SignIn(null,$this);
		$config->__stan = $this->user_stanowisko = (is_object($this->__logged_user)) ? $this->__logged_user->stanowisko : null;

	}

	/**
	 * impress ewery move in website for current session
	 *
	 */
	public function Impress() {
		if ($this->native_session_id) {
			$result = tools::__adodb("exec","UPDATE ".SESSI." SET ostatnie_dzialanie = strftime('%Y-%m-%d %H:%M:%S','now')
				WHERE id = " . $this->native_session_id);
		};
	}

	
	/**
	 * chack is user is logged in
	 *
	 * @return Bool
	 */
	public function IsLoggedIn() {
		return($this->logged_in);
	}

	/**
	 * return logged user ID
	 *
	 * @return Int
	 */
	public function GetUserID() {
		if ($this->logged_in) {
			return($this->user_id);
		} else {
			return(false);
		};		
	}

	/**
	 * return logged user object
	 *
	 * @return Object
	 */
	public function GetUserObject() {
		if ($this->logged_in) {
			$user = new UserController($this->user_id);
			return $user;
		};
	}
	
	public function GetUserData($column) {
		if ($this->logged_in) {
			$user = new UserController($this->user_id);
			return $user->$column;
		};
	}
		

	/**
	 * return session ID
	 *
	 * @return String
	 */
	public function GetSessionIdentifier() {
		return($this->php_session_id);
	}

	/**
	 * add user id to session if user is registred
	 *
	 * @param unknown_type $strUsername
	 * @param unknown_type $strPlainPassword
	 * @return unknown
	 */
	public function Login($strUsername, $strPlainPassword) {
		$strMD5Password = md5($strPlainPassword);
		$result = tools::__adodb("getOne","SELECT id FROM ".USERS." WHERE nazwa_uzytkownika = '$strUsername' AND md5_haslo = '$strMD5Password'");
		if (  $result >= 1) {
			$this->user_id = $result;
			$this->logged_in = true;
			$result = tools::__adodb("exec","UPDATE ".SESSI." SET zalogowany = 1, identyfikator_uzytkownika = " . $this->user_id . " 
				WHERE id = " . $this->native_session_id);
			return(true);
		} else {
			return(false);
		};
	}

	
	public function LogOut() {
		global $config;
		if ($this->logged_in == true) {
			$result = tools::__adodb("exec","UPDATE ".SESSI." SET zalogowany = 0, identyfikator_uzytkownika = 0 
				WHERE id = " . $this->native_session_id);
			
			$this->logged_in = false;
			$this->user_id = 0;
			$config->__user;
			$config->__logg = 0;
			$config->__stan = null;
			
			session_destroy();
			return(true);
		} else {
			return(false);
		};
	}

	/**
	 * get value of session var
	 *
	 * @param String $nm - session var name
	 * @return Strinf
	 */
	public function __get($nm) {
		$__wartosc_zmiennej = "SELECT wartosc_zmiennej FROM ".SESSV." 
			WHERE identyfikator_sesji = '" . $this->native_session_id . "' AND nazwa_zmiennej = '" . $nm . "'";
		
		$result = tools::__adodb("getOne",$__wartosc_zmiennej);
		if ( !empty($result) )  {
			$__value = unserialize($result);
			return($__value);
		} else {
			return(false);
		};
	}

	/**
	 * add new session var width his value
	 *
	 * @param String $nm
	 * @param String $val
	 */
	public function __set($nm, $val) {
		$__is_set = "SELECT COUNT(*) FROM ".SESSV." 
			WHERE identyfikator_sesji = '" . $this->native_session_id . "' AND nazwa_zmiennej = '" . $nm . "'";
		$result = tools::__adodb("getOne",$__is_set);
		
		$strSer = serialize($val);
		
		if ( $result == 0) {		
			 tools::__adodb("exec","BEGIN;");
			$stmt = "INSERT INTO ".SESSV." (id,identyfikator_sesji, nazwa_zmiennej, wartosc_zmiennej) 
				VALUES (NULL,'" . $this->native_session_id . "', '$nm', ".tools::__mres($strSer).")";
			$result = tools::__adodb("exec",$stmt);
			 tools::__adodb("exec","END;");
		}else{
			 tools::__adodb("exec","BEGIN;");
			$__q_update_sess_var = "UPDATE ".SESSV." SET wartosc_zmiennej = ".tools::__mres($strSer)."  WHERE identyfikator_sesji = ".tools::__mres($this->native_session_id)." AND nazwa_zmiennej = ".tools::__mres($nm);
			$result = tools::__adodb("exec",$__q_update_sess_var);		
			 tools::__adodb("exec","END;");	
		}
	}

	/**
	 * Set user ID and chack is hi logged in
	 *
	 * @return Array
	 */
	protected function _get_status_user_info(){
		$__q_user_info = "SELECT identyfikator_uzytkownika, zalogowany  FROM ".SESSI." WHERE identyfikator_sesji_ascii = '".$this->GetSessionIdentifier()."'";
		$__user_info = tools::__adodb("getRow",$__q_user_info);
		return $__user_info;
	}

	
	private function _session_open_method($save_path, $session_name) {
		return(true);
	}

	public function _session_close_method() {
		return(true);
	}

	private function _session_read_method($id) {
		# Służy do ustalenia, czy nasza sesja w ogóle istnieje
		$this->php_session_id = $id;
		# Na razie ustawia znacznik niepowodzenie na 1
		$failed = 1;
		# Sprawdza czy sesja istnieje w bazie danych
		$result = tools::__adodb("getRow","SELECT id, zalogowany, identyfikator_uzytkownika FROM ".SESSI." WHERE identyfikator_sesji_ascii = '$id'");
		if ( isset($result['id']) ) {
			//$row = sqlite_fetch_array($result);
			$this->native_session_id = $result["id"];
			if ($result["zalogowany"] == 1) {
				$this->logged_in = true;
				$this->user_id = $result["identyfikator_uzytkownika"];
			} else {
				$this->logged_in = false;
			};
		} else {
			$this->logged_in = false;
			tools::__adodb("exec","BEGIN;");
			# Konieczne jest stworzenie wpisu w bazie danych
			$result = tools::__adodb("exec","INSERT INTO ".SESSI." (identyfikator_sesji_ascii, zalogowany, identyfikator_uzytkownika, utworzono, user_agent) VALUES ('$id',0,0,strftime('%Y-%m-%d %H:%M:%S','now'),'{$this->subdomena}')");
			tools::__adodb("exec","END;");
			# Teraz pobiera prawdziwy identyfikator
			$result = tools::__adodb("getOne","SELECT id from ".SESSI." WHERE identyfikator_sesji_ascii = '$id'");
			//$row = sqlite_fetch_array($result);
			$this->native_session_id = $result;
		};
		# Zwraca jedynie ci�g pusty
		return("");
	}

	public function _session_write_method($id, $sess_data) {
		return(true);
	}

	private function _session_destroy_method($id) {
		$result = tools::__adodb("exec","DELETE FROM ".SESSI." WHERE identyfikator_sesji_ascii = '$id'");
		$this->_session_delete_arch();
		return($result);
	}


	private function _session_gc_method($maxlifetime) {
		return(true);
	}

	private function _session_delete_arch(){
		$__vars = "DELETE FROM ".SESSV." WHERE  identyfikator_sesji IN (SELECT id FROM ".SESSI." WHERE  ((strftime('%s','now') - strftime('%s',utworzono) ) > ' " . $this->session_lifespan . "') 
			AND ((strftime('%s','now') - strftime('%s',ostatnie_dzialanie) ) > '".$this->session_timeout."' 
			OR ostatnie_dzialanie IS NULL))";
		tools::__adodb("exec",$__vars);
		$__stmt = "DELETE FROM ".SESSI." WHERE  ((strftime('%s','now') - strftime('%s',utworzono) ) > ' " . $this->session_lifespan . "') 
			AND ((strftime('%s','now') - strftime('%s',ostatnie_dzialanie)) > '".$this->session_timeout."' 
			OR ostatnie_dzialanie IS NULL)";
		$result = tools::__adodb("exec",$__stmt);
		return ($result);
	}
}
